package com.education.ai.service.impl;

import com.education.ai.entity.Student;
import com.education.ai.entity.Class;
import com.education.ai.entity.Exercise;
import com.education.ai.dao.StudentDao;
import com.education.ai.service.StudentService;
import com.education.ai.service.ExerciseService;
import com.education.ai.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class StudentServiceImpl implements StudentService {

    private static final Logger log = LoggerFactory.getLogger(StudentServiceImpl.class);

    @Autowired
    private StudentDao studentDao;
    
    @Autowired
    private ExerciseService exerciseService;
    
    @Autowired
    private AuthService authService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<Student> findAll() {
        return studentDao.findAll();
    }

    @Override
    public Student findById(Long id) {
        return studentDao.findById(id)
                .orElseThrow(() -> new RuntimeException("未找到学生，ID: " + id));
    }

    @Override
    @Transactional
    public Student save(Student student) {
        return studentDao.save(student);
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        studentDao.delete(id);
    }

    @Override
    public List<Student> findByGrade(String grade) {
        return studentDao.findByGrade(grade);
    }

    @Override
    public List<Student> findByClassId(String classId) {
        return studentDao.findByClassId(classId);
    }

    @Override
    public List<Student> findByClassName(String className) {
        return studentDao.findByClassName(className);
    }

    @Override
    public List<Student> getStudentsByClassId(String classId, int page, int pageSize) {
        log.info("开始获取班级ID为[{}]的学生列表，页码: {}, 每页大小: {}", classId, page, pageSize);
        
        // 计算偏移量
        int offset = (page - 1) * pageSize;
        log.info("计算的SQL偏移量: {}", offset);
        
        // 1. 首先尝试通过class_id查询
        List<Student> students = studentDao.findByClassId(classId);
        log.info("通过class_id查询到{}名学生", students.size());
        
        // 2. 如果通过class_id没有找到学生，尝试通过班级名称查询
        if (students.isEmpty()) {
            // 获取班级名称 - 这里需要调整，因为我们没有实现ClassDao
            // 在后续完整实现中，应该添加ClassDao和其实现类
            log.info("未找到class_id对应的学生，尝试通过班级名称查询");
            // 临时方案：直接使用学生表中的班级名称进行查询
            students = studentDao.findByClassName(classId);
            log.info("通过班级名称查询到{}名学生", students.size());
        }
        
        // 4. 实现分页
        int start = offset;
        int end = Math.min(offset + pageSize, students.size());
        List<Student> pagedStudents = new ArrayList<>();
        if (start < students.size()) {
            pagedStudents = students.subList(start, end);
        }
        
        log.info("最终返回{}名学生", pagedStudents.size());
        return pagedStudents;
    }
    
    @Override
    public String getStudentIdFromToken(String token) {
        // 使用authService中的方法获取用户ID
        String userId = authService.getUserIdFromToken(token);
        Integer userRole = authService.getUserRoleFromToken(token);
        
        // 只有当用户角色是学生(2)时才返回学生ID
        if (userId != null && userRole != null && userRole == 2) {
            return userId;
        }
        
        log.warn("从Token中获取学生ID失败，Token无效或非学生用户");
        return null;
    }
    
    @Override
    public Student getCurrentStudent(String token) {
        String studentId = getStudentIdFromToken(token);
        if (studentId == null) {
            throw new RuntimeException("无法获取当前登录学生信息");
        }
        
        Optional<Student> studentOpt = studentDao.findByStudentId(studentId);
        if (!studentOpt.isPresent()) {
            throw new RuntimeException("学生信息不存在，学号: " + studentId);
        }
        
        return studentOpt.get();
    }
    
    @Override
    public Map<String, Object> getStudentLearningProgress(String studentId) {
        log.info("获取学生[{}]的学习进度数据", studentId);
        
        Optional<Student> studentOpt = studentDao.findByStudentId(studentId);
        if (!studentOpt.isPresent()) {
            throw new RuntimeException("学生信息不存在，学号: " + studentId);
        }
        
        Student student = studentOpt.get();
        
        // 创建结果集合
        Map<String, Object> progressData = new HashMap<>();
        
        // 添加基本学生信息
        progressData.put("studentName", student.getName());
        progressData.put("studentId", student.getStudentId());
        progressData.put("className", student.getClassName());
        progressData.put("grade", student.getGrade());
        
        // 查询学生练习会话数据，计算各科目进度
        String sql = "SELECT subject, SUM(correct_count) * 100.0 / SUM(question_count) as progress " +
                     "FROM student_practice_sessions " +
                     "WHERE student_id = ? " +
                     "GROUP BY subject";
        
        List<Map<String, Object>> subjectProgressResults = jdbcTemplate.queryForList(sql, studentId);
        
        // 转换为前端所需的格式
        List<Map<String, Object>> subjects = new ArrayList<>();
        for (Map<String, Object> row : subjectProgressResults) {
            Map<String, Object> subject = new HashMap<>();
            subject.put("id", subjects.size() + 1);
            
            // 将英文学科代码转换为中文学科名称
            String subjectCode = (String) row.get("subject");
            String subjectName = convertSubjectCodeToChinese(subjectCode);
            subject.put("name", subjectName);
            
            // 处理进度值
            Object progressObj = row.get("progress");
            if (progressObj != null) {
                // 安全处理数据库返回值，不管是BigDecimal还是Double类型
                double progressValue;
                if (progressObj instanceof BigDecimal) {
                    progressValue = ((BigDecimal) progressObj).doubleValue();
                } else if (progressObj instanceof Double) {
                    progressValue = (Double) progressObj;
                } else {
                    // 其他数字类型的处理
                    progressValue = Double.parseDouble(progressObj.toString());
                }
                // 四舍五入到整数
                subject.put("progress", (int) Math.round(progressValue));
            } else {
                // 默认进度为0
                subject.put("progress", 0);
            }
            
            subjects.add(subject);
        }
        
        // 如果没有任何科目的练习记录，提供空列表
        if (subjects.isEmpty()) {
            log.warn("学生[{}]没有练习记录，无法计算学习进度", studentId);
        }
        
        // 添加科目列表到结果
        progressData.put("subjects", subjects);
        
        // 获取最近练习数据统计
        Map<String, Object> recentPractice = getRecentPracticeStats(studentId);
        progressData.put("recentPractice", recentPractice);
        
        // 获取知识点掌握情况
        List<Map<String, Object>> knowledgePoints = getKnowledgePointsMastery(studentId);
        progressData.put("knowledgePoints", knowledgePoints);
        
        return progressData;
    }
    
    /**
     * 获取学生最近练习数据统计
     */
    private Map<String, Object> getRecentPracticeStats(String studentId) {
        Map<String, Object> recentPractice = new HashMap<>();
        
        try {
            // 统计总练习会话数
            String sessionSql = "SELECT COUNT(*) as total_sessions FROM student_practice_sessions WHERE student_id = ?";
            Object sessionsObj = jdbcTemplate.queryForObject(sessionSql, Object.class, studentId);
            
            int totalSessions = 0;
            if (sessionsObj != null) {
                if (sessionsObj instanceof BigDecimal) {
                    totalSessions = ((BigDecimal) sessionsObj).intValue();
                } else if (sessionsObj instanceof Number) {
                    totalSessions = ((Number) sessionsObj).intValue();
                } else {
                    totalSessions = Integer.parseInt(sessionsObj.toString());
                }
            }
            
            recentPractice.put("totalSessions", totalSessions);
            
            // 统计总题目数和正确题目数
            String exerciseSql = "SELECT SUM(question_count) as total, SUM(correct_count) as correct " +
                              "FROM student_practice_sessions WHERE student_id = ?";
            Map<String, Object> exerciseStats = jdbcTemplate.queryForMap(exerciseSql, studentId);
            
            // 安全获取总题目数
            int totalExercises = 0;
            Object totalObj = exerciseStats.get("total");
            if (totalObj != null) {
                if (totalObj instanceof BigDecimal) {
                    totalExercises = ((BigDecimal) totalObj).intValue();
                } else if (totalObj instanceof Number) {
                    totalExercises = ((Number) totalObj).intValue();
                }
            }
            recentPractice.put("totalExercises", totalExercises);
            
            // 安全获取正确题目数
            int correctExercises = 0;
            Object correctObj = exerciseStats.get("correct");
            if (correctObj != null) {
                if (correctObj instanceof BigDecimal) {
                    correctExercises = ((BigDecimal) correctObj).intValue();
                } else if (correctObj instanceof Number) {
                    correctExercises = ((Number) correctObj).intValue();
                }
            }
            
            // 计算正确率
            double correctRate = totalExercises > 0 ? (double) correctExercises / totalExercises : 0;
            recentPractice.put("correctRate", Math.round(correctRate * 100) / 100.0); // 保留两位小数
            
            // 统计总练习时间(分钟)
            String timeSql = "SELECT SUM(duration) / 60 as total_time FROM student_practice_sessions WHERE student_id = ?";
            Object timeObj = jdbcTemplate.queryForObject(timeSql, Object.class, studentId);
            
            int totalTime = 0;
            if (timeObj != null) {
                if (timeObj instanceof BigDecimal) {
                    totalTime = ((BigDecimal) timeObj).intValue();
                } else if (timeObj instanceof Number) {
                    totalTime = ((Number) timeObj).intValue();
                } else {
                    totalTime = Integer.parseInt(timeObj.toString());
                }
            }
            
            recentPractice.put("totalTime", totalTime);
            
        } catch (Exception e) {
            log.error("获取学生练习统计数据失败", e);
            // 设置默认值
            recentPractice.put("totalSessions", 0);
            recentPractice.put("totalExercises", 0);
            recentPractice.put("correctRate", 0);
            recentPractice.put("totalTime", 0);
        }
        
        return recentPractice;
    }
    
    /**
     * 获取学生知识点掌握情况
     */
    private List<Map<String, Object>> getKnowledgePointsMastery(String studentId) {
        List<Map<String, Object>> knowledgePoints = new ArrayList<>();
        
        try {
            // 按知识点(topic)统计练习情况
            String kpSql = "SELECT subject, topic as name, SUM(correct_count) * 100.0 / SUM(question_count) as mastery " +
                         "FROM student_practice_sessions " +
                         "WHERE student_id = ? " +
                         "GROUP BY subject, topic " +
                         "ORDER BY mastery DESC " +
                         "LIMIT 5"; // 获取前5个熟练度最高的知识点
            
            List<Map<String, Object>> results = jdbcTemplate.queryForList(kpSql, studentId);
            
            for (Map<String, Object> row : results) {
                Map<String, Object> kp = new HashMap<>();
                kp.put("subject", row.get("subject"));
                kp.put("name", row.get("name"));
                
                // 处理熟练度值
                Object masteryObj = row.get("mastery");
                double masteryValue = 0;
                
                if (masteryObj != null) {
                    if (masteryObj instanceof BigDecimal) {
                        masteryValue = ((BigDecimal) masteryObj).doubleValue();
                    } else if (masteryObj instanceof Double) {
                        masteryValue = (Double) masteryObj;
                    } else {
                        // 其他数字类型的处理
                        masteryValue = Double.parseDouble(masteryObj.toString());
                    }
                }
                
                kp.put("mastery", masteryValue / 100); // 转换为0-1的小数
                
                knowledgePoints.add(kp);
            }
            
        } catch (Exception e) {
            log.error("获取学生知识点掌握情况失败", e);
        }
        
        return knowledgePoints;
    }
    
    @Override
    public List<Exercise> getRecommendedExercises(String studentId, String subject, String knowledgePoint) {
        log.info("获取学生[{}]的推荐习题，学科: {}, 知识点: {}", studentId, subject, knowledgePoint);
        
        // 检查学生是否存在
        Optional<Student> studentOpt = studentDao.findByStudentId(studentId);
        if (!studentOpt.isPresent()) {
            throw new RuntimeException("学生信息不存在，学号: " + studentId);
        }
        
        // 根据学科和知识点获取习题
        List<Exercise> exercises;
        if (knowledgePoint != null && !knowledgePoint.isEmpty()) {
            exercises = exerciseService.findBySubjectAndTopic(subject, knowledgePoint);
        } else {
            exercises = exerciseService.findBySubject(subject);
        }
        
        log.info("为学生推荐了{}道习题", exercises.size());
        
        // 如果有更多数据，可以根据学生的学习情况进行个性化推荐
        // 例如，根据学生的错题、弱点知识点等优先推荐相关习题
        // 这部分需要更复杂的逻辑和数据分析
        
        return exercises;
    }

    @Override
    public Student getStudentByStudentId(String studentId) {
        Optional<Student> studentOpt = studentDao.findByStudentId(studentId);
        if (!studentOpt.isPresent()) {
            return null;
        }
        return studentOpt.get();
    }
    
    @Override
    public Student saveStudent(Student student) {
        return studentDao.save(student);
    }
    
    @Override
    public boolean updatePassword(String studentId, String currentPassword, String newPassword) {
        // 获取学生信息
        Optional<Student> studentOpt = studentDao.findByStudentId(studentId);
        if (!studentOpt.isPresent()) {
            log.error("更新密码失败：学生ID {} 不存在", studentId);
            return false;
        }
        
        Student student = studentOpt.get();
        
        // 验证当前密码是否正确
        if (!student.getPassword().equals(currentPassword)) {
            log.warn("更新密码失败：当前密码不正确，学生ID: {}", studentId);
            return false;
        }
        
        // 更新密码
        student.setPassword(newPassword);
        studentDao.save(student);
        
        log.info("学生 {} 密码更新成功", studentId);
        return true;
    }

    /**
     * 将英文学科代码转换为中文学科名称
     */
    private String convertSubjectCodeToChinese(String subjectCode) {
        if (subjectCode == null) return "";
        
        switch (subjectCode.toLowerCase()) {
            case "chinese": return "语文";
            case "math": return "数学";
            case "english": return "英语";
            case "physics": return "物理";
            case "chemistry": return "化学";
            case "biology": return "生物";
            case "politics": return "政治";
            case "history": return "历史";
            case "geography": return "地理";
            default: return subjectCode; // 如果没有匹配，返回原始代码
        }
    }
} 